﻿package net.wangit.util;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public final class NamingUtil {

	private static final Log log = LogFactory
			.getLog(net.wangit.util.NamingUtil.class);

	@SuppressWarnings("unchecked")
	public static InitialContext getInitialContext(Hashtable hash)
			throws NamingException {

		if (log.isDebugEnabled())
			log.debug((new StringBuilder("JNDI InitialContext properties:"))
					.append(hash).toString());
		try {
			return hash.size() != 0 ? new InitialContext(hash)
					: new InitialContext();
		} catch (NamingException e) {
			log.error("Could not obtain initial context", e);
			throw e;
		}
	}

	public static void bind(Context ctx, String name, Object val)
			throws NamingException {
		try {
			if (log.isDebugEnabled())
				log.debug((new StringBuilder("binding: ")).append(name)
						.toString());
			ctx.rebind(name, val);
		} catch (Exception e) {
			Name n;
			for (n = ctx.getNameParser("").parse(name); n.size() > 1; n = n
					.getSuffix(1)) {
				String ctxName = n.get(0);
				Context subctx = null;
				try {
					if (log.isDebugEnabled())
						log.debug((new StringBuilder("lookup: ")).append(
								ctxName).toString());
					subctx = (Context) ctx.lookup(ctxName);
				} catch (NameNotFoundException namenotfoundexception) {
				}
				if (subctx != null) {
					if (log.isDebugEnabled())
						log.debug((new StringBuilder("Found subcontext: "))
								.append(ctxName).toString());
					ctx = subctx;
				} else {
					if (log.isDebugEnabled())
						log.debug((new StringBuilder("Creating subcontext: "))
								.append(ctxName).toString());
					ctx = ctx.createSubcontext(ctxName);
				}
			}

			if (log.isDebugEnabled())
				log
						.debug((new StringBuilder("binding: ")).append(n)
								.toString());
			ctx.rebind(n, val);
		}
		if (log.isDebugEnabled())
			log.debug((new StringBuilder("Bound name: ")).append(name)
					.toString());
	}

	private NamingUtil() {
	}

}
